﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Syspetro.Core;
using Syspetro.Deploy.AuthorizationReq;
using System.IO;

namespace Syspetro.Deploy.Jwt
{
    /// <summary>
    /// 认证
    /// </summary>
    public static class JwtAuthorizationExtensions
    {
        /// <summary>
        /// 对称加密授权
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddJwtHS(this IServiceCollection services)
        {
            services.Configure<JwtTokenOptions>(InternalApp.Configuration.GetSection("JWTSettings"));
            var tokenOptions = services.BuildServiceProvider().GetService<IOptions<JwtTokenOptions>>().Value;
            var Parameters = JWTEncryption.CreateTokenValidationParametersHs(tokenOptions);
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options => { options.TokenValidationParameters = Parameters; });
            services.SetAuthorization();
            services.AddScoped<IJwtService, JwtHSService>();
            services.AddScoped<ITokenCache, TokenMemoryCache>();
            return services;
        }
        /// <summary>
        /// 非对称加密授权（更适合独立的授权中心模式）
        /// </summary>
        /// <param name="services"></param>
        /// <param name="ExpiredTime"></param>
        /// <returns></returns>
        public static IServiceCollection AddJwtRS(this IServiceCollection services)
        {
            services.Configure<JwtTokenOptions>(InternalApp.Configuration.GetSection("JWTSettings"));
            string path = Path.Combine(Directory.GetCurrentDirectory(), "tokenkey.public.json");
            var tokenOptions = services.BuildServiceProvider().GetService<IOptions<JwtTokenOptions>>().Value;
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options => { options.TokenValidationParameters = JWTEncryption.CreateTokenValidationParametersRs(tokenOptions, path); });
            services.SetAuthorization();
            services.AddScoped<IJwtService, JwtRSService>();
            services.AddScoped<ITokenCache, TokenMemoryCache>();
            return services;
        }
        /// <summary>
        /// 添加认证策略
        /// </summary>
        /// <param name="services"></param>
        /// <param name="enableGlobalAuthorize">是否启用全局授权</param>
        public static IServiceCollection SetAuthorization(this IServiceCollection services, bool enableGlobalAuthorize = false)
        {
            //services.AddAuthorization(options =>
            //{
            //    options.AddPolicy("AdminPolicy", policyBuilder => policyBuilder.AddRequirements(new AdminExtendRequirement()));
            //});
            //services.AddSingleton<IAuthorizationHandler, AdminExtendRequirementHandler>();

            services.AddAuthorization();
            services.AddSingleton<IAuthorizationPolicyProvider, CustomPolicyProvider>();
            services.AddSingleton<IAuthorizationHandler, CustomExtendRequirementHandler>();
            if (enableGlobalAuthorize)
            {
                services.Configure<MvcOptions>(options =>
                {
                    options.Filters.Add(new AuthorizeFilter());
                });
            }
            return services;
        }
    }
}
